/* $RCSFile: PortalPagesManager.ascx.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice/PageModules/Pages/PortalPagesManager.ascx.cs $
 * $log$
 * Revision 20 2010/08/09 10:51:22  christian.surieux
 *   Added Log comment to all .aspx .ascx .master files
 * Revision 19 2010/08/09 09:43:58  christian.surieux
 *   Added Log to cs sources files
 * Revision 6 2010/08/06 19:56:26  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;

using AddonNice.Diagnostics;
using AddonNice.Core;
using AddonNice.Design;
using AddonNice.Helpers;
using AddonNice.Configuration;
using AddonNice.Configuration.Settings;
using AddonNice.Settings;
using AddonNice.Settings.Cache;
using AddonNice.UI.DataTypes;
using AddonNice.UI.WebControls;

using Telerik.Web.UI;

using Trace2 =  System.Diagnostics.Trace;

namespace AddonNice.PageModules.Pages 
{
        
 	#region Local TraceSwitch 
	public class PagesManagerTrace : ADNTraceSwitch
	{
		static public ADNTraceSwitch	Sw	=	new ADNTraceSwitch("PagesManagerTrace","Special Trace Switch for Pages Manager");
	}
	#endregion Local TraceSwitch 

    public class AStr
    {
            public const string showAdmin           =   "AM_SHOW_ADMIN";
            public const string moveAdmin           =   "AM_MOVE_ADMIN";
            public const string moveCommon          =   "AM_MOVE_COMMON";
            public const string skipList            =   "AM_PAGES_SKIP_LIST";
            public const string skipModulesList     =   "AM_PAGES_SKIP_MOD_LIST";
    }

    /// <summary>
    /// Initializer class for PortalPagesManager 
    /// </summary>
    public class PortalPagesManagerSI : PortalModuleControlSI
    {
        public PortalPagesManagerSI(ModuleSettingsDictionary bSettings,ISettingsOwner pm) : base()
        {
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PortalPagesManagerSI Ctor BEG.",ModuleTraceSwitch.Sw.Info);
            InitSettings(bSettings,pm);
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PortalPagesManagerSI Ctor END.",ModuleTraceSwitch.Sw.Info);
        }
 
        public override void InitSettings(ModuleSettingsDictionary bSettings,ISettingsOwner pm)
        {             
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]PortalPagesManagerSI InitSettings BEG.",ModuleTraceSwitch.Sw.Info);
            
            base.InitSettings(bSettings,pm);

            string extgrp                       =   pm.ExtendedResourcesGroup;

            // Admin pages : false by default
			SettingItemSpecial showAdmin	    =	new SettingItemSpecial(AStr.showAdmin,new BooleanDataType());
			showAdmin.Value		                =	"false";        
			showAdmin.Order		                =	10;        
			showAdmin.ExtendedGroupName         =   extgrp;
            showAdmin.Description		        =	"Should the module show site Admin pages";
			showAdmin.EnglishName		        =	"Show Admin";
			bSettings.AddSetting(showAdmin);

            // SkipPages List
			SettingItemSpecial skipList	        =	new SettingItemSpecial(AStr.skipList,new StringDataType());
			skipList.Order			            =	20;
			skipList.ExtendedGroupName          =   extgrp;
            skipList.Description		        =	"Semicolon separated list of page IDs that should be skipped";
			skipList.EnglishName		        =	"Page skip List";
			bSettings.AddSetting(skipList);
            
            
			SettingItemSpecial skipModulesList  =	new SettingItemSpecial(AStr.skipModulesList,new StringDataType());
			skipModulesList.Order			    =	25;
			skipModulesList.ExtendedGroupName   =   extgrp;
            skipModulesList.Description		    =	"Semicolon separated list of Modules IDs that should be skipped";
			skipModulesList.EnglishName		    =	"Modules skip List";
			bSettings.AddSetting(skipModulesList);
            
            SettingItemSpecial moveAdmin	    =	new SettingItemSpecial(AStr.moveAdmin,new BooleanDataType());
			moveAdmin.Value		                =	StStr.strFalse;        
			moveAdmin.Order		                =	30;        
			moveAdmin.ExtendedGroupName         =   extgrp;
            moveAdmin.Description		        =	"Is moving Admin nodes allowed";
			moveAdmin.EnglishName		        =	"Move Admin nodes";
			bSettings.AddSetting(moveAdmin);

            SettingItemSpecial moveCommon	    =	new SettingItemSpecial(AStr.moveCommon,new BooleanDataType());
			moveCommon.Value		            =	StStr.strFalse;        
			moveCommon.Order		            =	40;        
			moveCommon.ExtendedGroupName        =   extgrp;
            moveCommon.Description		        =	"Is moving Common nodes allowed";
			moveCommon.EnglishName		        =	"Move common nodes";
			bSettings.AddSetting(moveCommon);

            if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PortalPagesManagerSI InitSettings END.",ModuleTraceSwitch.Sw.Info);
        }
    }

    public partial class PortalPagesManager : PortalModuleControl
    {
        #region Properties and const

        PagesDB pagesDB		        =   new PagesDB();
        const string strPageMenu    =   "PageMenu";

        public string ConfirmText
        {
            get
            {
                return LocalizeHelper.Localize("CONFIRM_DELETEPAGE","Confirm deleting this page ?");
            }
        }
        public string ConfirmTitle
        {
            get
            {
                return LocalizeHelper.Localize("DELETE","Delete");
            }
        }
        
        #endregion Properties and const

        #region Global Implementation

        public override Guid GuidID 
        {
            get
            {
				return new Guid(StStr.PortalPagesManagerGuid);
			}
        }

		public override bool AdminModule
		{
			get
			{
				return true;
			}
        }
        #endregion Global Implementation

        #region Ctor and Initializer

        /// <summary>
        /// We Add parameters to format display, note that these parameters are also used in the TabLayout and AddPage windows
        /// because theses windows normally load this module parameters as the mId parameter is addede to query string
        /// </summary>
        public PortalPagesManager()
		{
			if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PortalPagesManager Ctor BEG.",ModuleTraceSwitch.Sw.Info);

            if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PortalPagesManager Ctor END.",ModuleTraceSwitch.Sw.Info);
        }

        public override string ExtendedResourcesGroup 
		{
            get
            {
       			const string extgrp                 =   "PAGEMANAGER";
                return extgrp;
            }
		}

        public override void InitPortalModuleControl(ModuleSettingsDictionary bSettings)
        {
            PortalModuleInitializer =   new PortalPagesManagerSI(bSettings,this);
        }

        #endregion Ctor

        /// <summary>
        /// Install all AjaxSettings
        /// As we change the Menu herachy, we must add any menu in necessary ajaxsettings to refresh them on callback
        /// </summary>
        private void Page_Load(object sender, EventArgs e) 
        {
			if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager Page_Load IsPostBack: {0}, IsInAsyncPostBack: {1}",Page.IsPostBack,IsInAsyncPostBack),ModuleTraceSwitch.Sw.Info);
            AddAjaxSetting(GridDock,RadTree1);
            // PortalMenus are refreshed by this button
            portalSettings.ExecForEachMenu(delegate(IPortalMenu menu)
                { AddAjaxSetting(GridDock, menu.AjaxControl); });

            AddAjaxSetting(RadTree1,RadTree1);
            RadGrid RadGrid2    =   (RadGrid)GridDock.ContentContainer.FindControl("RadGrid2");
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager Page_Load RadGrid2 null: {0}.", RadGrid2 == null ),PagesManagerTrace.Sw.Info);
            if (RadGrid2 != null)
            {
                AddAjaxSetting(RadTree1, RadGrid2);
            }
            // PortalMenus are refreshed by this treeview
            portalSettings.ExecForEachMenu(delegate(IPortalMenu menu)
            { AddAjaxSetting(RadTree1, menu.AjaxControl); });

            // If this is the first visit to the page, bind the tab data to the page treeview
            if (!Page.IsPostBack) 
            {
                BuildTreeView();
				// After up or down button when the page is refreshed, 
				// select the previously selected tab from the list.
                if (Request.Params[StStr.selectedItem] != null) 
				{
					try
					{
                        string strTabIndex			=   Request.Params[StStr.selectedItem];
			            if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager Page_Load SelectPage: {0}",strTabIndex),PagesManagerTrace.Sw.Info);
						SelectPage(strTabIndex,RadTree1.Nodes);
					}
					catch(Exception ex)
					{
			            if (ModuleTraceSwitch.Sw.TraceError)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager Page_Load SelectPage ex: {0}",ex),ModuleTraceSwitch.Sw.Info);
					}
				}
            }
        }

        #region Build Treeview and context menu

        internal class sortNode
        {
            public int parentId;
            public RadTreeNode nd;
        }

        /// <summary>
        /// Build the treeview with pages from classic view
        /// </summary>
        private void BuildTreeView()
        {
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( "[V]PortalPagesManager BuildTreeView BEG",PagesManagerTrace.Sw.Info);
            bool showAdmin                  =   Settings[AStr.showAdmin].ToBool();
            bool moveCommon                 =   Settings[AStr.moveCommon].ToBool();
            // insert context menu
            RadTree1.ContextMenus.Add(CreateContextMenu());
            //read pages from DB
            SqlDataReader dr                =   null;
            try
            {
                dr                          =   pagesDB.GetAllPortalPages(PortalID);
                string strRoot              =   LocalizeHelper.Localize("ROOT_LEVEL","Root");
                RadTreeNode root            =   new RadTreeNode(strRoot, "0");
                RadTree1.Nodes.Add(root);
                Hashtable skTb              =   portalSettings.GetSkinImageMenu(true);
                List<sortNode> parenNFnd    =   new List<sortNode>();
                while (dr.Read())
                {
                    int tabId               =   (int)dr[StStr.DBPageID];
                    int wportalId           =   (int)dr[StStr.DBPortalID];
                    int parentTabId         =   Convert.IsDBNull(dr[StStr.DBParentPageID]) ? 0 : (int)dr[StStr.DBParentPageID];
                    bool hasModules         =   ((int)dr[StStr.DBPageNbModules]) != 0;
                    RadTreeNode nd          =   new RadTreeNode(string.Format("{0}-{1}",tabId,(string)dr[StStr.DBPageName]), tabId.ToString());
                    // don't move pages from common portal
                    if ( wportalId == StStr.CommonPortalID && !moveCommon )
                        nd.AllowDrag        =   false;
                    RadTreeNode nd1         =   RadTree1.FindNodeByValue(parentTabId.ToString());
                    string wSkinID          =   ((string)dr[StStr.DBPageSkin]).ToLower(CultureInfo.InvariantCulture).Trim();
                    bool okSkin             =   (skTb[wSkinID] != null);
                    if (okSkin)
                    {
                        nd.Attributes["Skin"]   =   (string)skTb[wSkinID];
                    }
                    else
                    {
                        nd.Attributes["Skin"]   =   (string)skTb["defaultskin"];
                    }
                    if (nd1 == root)
                    {
                        nd.ImageUrl         =   nd.Attributes["Skin"];
                        if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager BuildTreeView nd.ImageUrl: {0}", nd.ImageUrl),PagesManagerTrace.Sw.Info);
                    }
                    if (nd1 != null)
                    {
                        if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager BuildTreeView Adding {0} to {1}", nd.Text, nd1.Text),PagesManagerTrace.Sw.Info);
                        nd1.Nodes.Add(nd);
                    }
                    else
                    {
                        if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager BuildTreeView parent not readen nd:{0}, parentTabId: {1}.", nd.Text, parentTabId),PagesManagerTrace.Sw.Info);
                        parenNFnd.Add(new sortNode() { parentId = parentTabId,nd = nd });
                    }
                    // We check for children already readen
                    for ( int i=0 ; i < parenNFnd.Count ; i++ )
                    {
                        sortNode sn         =   parenNFnd[i];
                        if ( sn.parentId == tabId )
                        {
                            if (PagesManagerTrace.Sw.TraceVerbose)
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager BuildTreeView child node found nd:{0}, child: {1}.", nd.Text, sn.nd.Text),PagesManagerTrace.Sw.Info);
                            nd.Nodes.Add(sn.nd);
                            parenNFnd.RemoveAt(i);
                            i--;
                        }
                    }
                }
                // We need to close before SelectNode
                if (dr != null)
                    dr.Close();
                // Add the not found nodes to root
                for ( int i=0 ; i < parenNFnd.Count ; i++ )
                {
                    sortNode sn             =   parenNFnd[i];
                    if (PagesManagerTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager BuildTreeView node without parent added to root nd:{0}, parentId: {1}.", sn.nd.Text, sn.parentId),PagesManagerTrace.Sw.Info);
                    root.Nodes.Add(sn.nd);
                }
                root.Expanded               =       true;
                // find a first node to open
                if ( root.Nodes.Count > 1 )
                {
                    RadTreeNode nd1         =   null;
                    int id                  =   StStr.WelcomePageID;
                    while (nd1 == null)
                    {
                        nd1                 =   RadTree1.FindNodeByValue(id.ToString());
                        if (nd1 != null)
                        {
                            SelectNode(nd1);
                            nd1.Expanded    =   true;
                            break;
                        }
                        if (id == StStr.WelcomePageID)
                            id              =   StStr.CrmPagesPageID;
                        else if (id == StStr.CrmPagesPageID)
                            id              =   StStr.WebPagesPageID;
                        else if (id == StStr.WebPagesPageID)
                            id              =   StStr.SepPageID;
                        else if (id == StStr.SepPageID)
                            id              =   StStr.ReportsPageID;
                        else break;
                    }
                }
                if ( !showAdmin )
                {
                    RadTreeNode nd          =   root.Nodes.FindNodeByValue(StStr.strPageAdminID);
                    {
                        if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine("[V]PortalPagesManager BuildTreeView removing Admin node.", PagesManagerTrace.Sw.Info);
                        if (nd != null)
                            root.Nodes.Remove(nd);
                    }
                }
                // Should we skip any Page ?
                string SkipPageList         =   Settings[AStr.skipList].Value;
                if (PagesManagerTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager BuildTreeView SkipPageList: [{0}]", SkipPageList), PagesManagerTrace.Sw.Info);
                if (!string.IsNullOrEmpty(SkipPageList))
                {
                    string[] pgID           =   SkipPageList.Split(new char[]{';'},StringSplitOptions.RemoveEmptyEntries);
                    for (int i=0; i < pgID.Length ; i++ )
                    {
                        if ( string.IsNullOrEmpty(pgID[i] ) )
                            continue;
                        RadTreeNode nd      =   RadTree1.FindNodeByValue(pgID[i]);
                        if (nd != null)
                        {
                            if (PagesManagerTrace.Sw.TraceVerbose)
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager BuildTreeView Removing PageID: {0}", pgID[i]), PagesManagerTrace.Sw.Info);
                            nd.Owner.Nodes.Remove(nd);
                        }
                    }
                }
                if (PagesManagerTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( "[V]PortalPagesManager BuildTreeView END",PagesManagerTrace.Sw.Info);
            }
            catch (Exception ex)
            {
                if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager Page_Load ex:{0}", ex),ModuleTraceSwitch.Sw.Info);
                throw;
            }
            finally
            {
                if (dr != null)
                    dr.Close();
            }
        }
        
		/// <summary>
		/// Create the context menu for treeview
		/// </summary>
		RadTreeViewContextMenu CreateContextMenu()
		{
			RadTreeViewContextMenu cm	=   new RadTreeViewContextMenu();
            cm.ID                       =   strPageMenu;

            RadMenuItem cmi			    =	new RadMenuItem();
			cmi.Value		            =	"EditPage";
            cmi.ImageUrl                =   portalSettings.GetImageFromThemeSkins("EditBtn");

			cmi.Text			        =	LocalizeHelper.Localize("AM_CONTEXT_EDITPAGE","Edit Page");
			cmi.PostBack		        =	true;
			cm.Items.Add(cmi);

			cmi					        =	new RadMenuItem();
			cmi.Value			        =	"DeletePage";
            cmi.ImageUrl                =   portalSettings.GetImageFromThemeSkins("DeleteBtn");
			cmi.Text			        =	LocalizeHelper.Localize("AM_CONTEXT_DELETEPAGE","Delete Page");
			cmi.PostBack		        =	true;
			cm.Items.Add(cmi);

			cmi					        =	new RadMenuItem();
			cmi.Value			        =	"CopyPage";
            cmi.ImageUrl                =   portalSettings.GetImageFromThemeSkins("AddPage");
			cmi.Text			        =	LocalizeHelper.Localize("AM_CONTEXT_COPYPAGE","Copy Page");
			cmi.PostBack		        =	true;
			cm.Items.Add(cmi);

			cmi					        =	new RadMenuItem();
			cmi.Value			        =	"AddPage";
            cmi.ImageUrl                =   portalSettings.GetImageFromThemeSkins("AddPage");
			cmi.Text			        =	LocalizeHelper.Localize("AM_CONTEXT_ADDPAGE","Add Page");
			cmi.PostBack		        =	true;
			cm.Items.Add(cmi);

            cmi                         =	new RadMenuItem();
			cmi.Value			        =	"AddDumPage";
            cmi.ImageUrl                =   portalSettings.GetImageFromThemeSkins("AddPage");
			cmi.Text			        =	LocalizeHelper.Localize("SITEMAP_ADDDUMMYPAGE","Add dummy page");
			cmi.PostBack		        =	true;
			cm.Items.Add(cmi);

            cmi                         =	new RadMenuItem();
			cmi.Value			        =	"Jump2Page";
            cmi.ImageUrl                =   portalSettings.GetImageFromThemeSkins("Buttons_Right");
			cmi.Text			        =	LocalizeHelper.Localize("AM_CONTEXT_JUMP2PAGE","Jump toPage");
			cmi.PostBack		        =	true;
			cm.Items.Add(cmi);

            return cm;
		}
		
        #endregion Build Treeview and context menu

        // To reflect current changes in portalMenu
        void ReloadPortal()
        {
            CurrentCache.RemoveGlobalPagesCacheKey();
            CurrentCache.RemoveAll(StStr.PageNavigationSettings);
            CurrentCache.RemoveAll(StStr.AuthorizedPageStripDetail);
		    portalSettings.ReloadPortal(true);
            portalSettings.ReloadMenus();
        }

		/// <summary>
		/// Delete Page corresponding to node 
		/// </summary>
		protected void DeletePage(RadTreeNode nd)
        {
            try
            {
                // must delete from database too
				int id			    =   int.Parse(nd.Value);
				if (PagesManagerTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager DeletePage node: {0}-{1}", nd.Text, nd.Value),PagesManagerTrace.Sw.Info);
                pagesDB.DeletePage(id);
                RadTreeNode ndP     =   nd.ParentNode;
				nd.Owner.Nodes.Remove(nd); 
                SelectNode(ndP);
                ReloadPortal();
            }
            catch (Exception ex)
            {
                if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager DeletePage ex:{0}", ex ),ModuleTraceSwitch.Sw.Info);
                Controls.Add(new LiteralControl("<br><span class='Error'>" + AddonNice.Helpers.LocalizeHelper.Localize("TAB_DELETE_FAILED", "Failed to delete Page") + "<br>"));
            }
        }

        /// <summary>
		/// Handler for a right button menu click in treeView
		/// </summary>
        void RadTree1_ContextMenuItemClick(object o, RadTreeViewContextMenuEventArgs e)
        {
			string contextCommand = e.MenuItem.Value;
			
			RadTreeNode currentNode = e.Node;

			switch (contextCommand)
			{
				case "DeletePage":          
					DeletePage( currentNode);   
					break;
				case "EditPage":    
					EditPage(currentNode);
					break;
				case "AddPage":
					AddPage(currentNode);
					break;
				case "CopyPage":
					CopyPage(currentNode);
					break;
				case "AddDumPage":
					AddDumPage(currentNode);
					break;
                case "Jump2Page":
                    if (currentNode != null) 
                        Jump2Page(currentNode);
                    break;
			}
		}
		
        /// <summary>
        /// Add a new page under current node in site map
        /// </summary>
        private void AddDumPage(RadTreeNode currentNode)
        {
            string DBAllUser        =   Config.InternallAllUsersRole;
            string DBAllUser2       =   DBAllUser+";";
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager AddDumPage BEG authorizedRoles : {0}", DBAllUser2),PagesManagerTrace.Sw.Info);

			// Add Page info in the database
			int NewPageID       =   0;
            string strNodeDummy =   LocalizeHelper.Localize("SITEMAP_DUMMYPAGE","Dummy Menu Page");
            try
            {
                portalSettings.FlushSkinImageMenuCache();
                NewPageID       =   pagesDB.AddPage(portalSettings.PortalID, Int32.Parse(currentNode.Value), strNodeDummy,StStr.strDefaultSkin, 990000
                    ,3,0,0,0,0,0, DBAllUser2);
                //rename it to include page number
                strNodeDummy    =   string.Format("{0}({1})",strNodeDummy,NewPageID);
                pagesDB.UpdatePageName(NewPageID,strNodeDummy);
                if (PagesManagerTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager AddDumPage Added NewPageId: {0}", NewPageID),PagesManagerTrace.Sw.Info);
            }
            catch (Exception exp)
            {
                if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager AddDumPage ex : {0}", exp),ModuleTraceSwitch.Sw.Info);
                throw;
            }
            RadTreeNode nd          =   new RadTreeNode(string.Format("{0}-{1}",NewPageID,strNodeDummy), NewPageID.ToString());
            nd.ContextMenuID        =   strPageMenu;
            currentNode.Nodes.Add(nd);
            Hashtable skTb          =   portalSettings.GetSkinImageMenu(true);
            nd.Attributes["Skin"]   =   (string)skTb["seppagesskin"];
            if (( nd.ParentNode != null ) && (nd.ParentNode.ParentNode == null ) )
                    nd.ImageUrl     =   nd.Attributes["Skin"];
            else    nd.ImageUrl     =   string.Empty;
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager AddDumPage END Added NewPageId: {0}, CurrentNode: {1}", NewPageID,currentNode.Value),PagesManagerTrace.Sw.Info);
		}

        void GridDock_Command(object sender, DockCommandEventArgs e)
        {
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager GridDock_Command BEG name: {0}.", e.Command.Name),PagesManagerTrace.Sw.Info);
            RadTreeNode nd = RadTree1.SelectedNode;
            if ( nd == null )
                return;
            switch (e.Command.Name)
            {
                case "EditBtn":
					EditPage(nd);
                    break;
                case "DeleteBtn":
					DeletePage(nd);   
                    break;
                case "addTab":
                    AddPage(nd);
                    break;
                case "copyTab":
                    CopyPage(nd);
                    break;
                case "Jump2Page":
                    if (nd != null) 
                        Jump2Page(nd);
                    break;
            }
        }

        /// <summary>
        /// Add a new sub-page to selected node
        /// </summary>
		void AddPage(RadTreeNode nd)
		{
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager AddPage BEG nd.Text: {0}", nd.Text),PagesManagerTrace.Sw.Info);
            int newParentID     =   StStr.parentDBIdNotSet;
            if (nd != null) 
                int.TryParse(nd.Value,out newParentID);
            string strarg       =   string.Format("Mid={0}&{1}={2}&parentpageid={3}",
                new object[]{ModuleID,StStr.returnPageID,ADNPage.PageID,newParentID});
            // it will use newParentID as its model for settings
            string strredirect  =   HttpUrlBuilder.BuildUrlWithCustomAttributes(Config.ModulesPath + "/Pages/AddPage.aspx",newParentID, strarg);
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager AddPage url:{0}", strredirect),PagesManagerTrace.Sw.Info);
            //Response.Redirect(strredirect);
            ADNPage.Redirect(strredirect,true);
		}

        protected void EditPage(RadTreeNode nd)
        {
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager EditPage BEG nd.Text: {0}", nd.Text),PagesManagerTrace.Sw.Info);
			if (nd != null) 
            {
                // returnPageID is the desired return Page ID, so here we add this Page
                int newParentID     =   StStr.parentDBIdNotSet;
                int.TryParse(nd.Value,out newParentID);
                string strarg       =   string.Format("Mid={0}&{1}={2}", ModuleID,StStr.returnPageID,PageID);
                string strredirect  =   HttpUrlBuilder.BuildUrlWithCustomAttributes(Config.ModulesPath + "/"+Config.PageLayoutPage, newParentID, strarg);
                if (PagesManagerTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager EditPage url:{0}", strredirect),PagesManagerTrace.Sw.Info);
                ADNPage.Redirect(strredirect,true);
                //Response.Redirect(strredirect);
			}
        }

        /// <summary>
        /// Redirect to selected Page
        /// </summary>
        protected void Jump2Page(RadTreeNode nd)
		{
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager Jump2Page BEG nd.Text: {0}", nd.Text),PagesManagerTrace.Sw.Info);
            int tabID               =   0;
            if (int.TryParse(nd.Value, out tabID))
            {
                string returnTab    =   HttpUrlBuilder.BuildUrl(tabID);
                ADNPage.Redirect(returnTab,true);
            }
        }

        protected void CopyPage(RadTreeNode nd)
        {
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager CopyPage BEG nd.Text: {0}", nd.Text),PagesManagerTrace.Sw.Info);
            int tabID                           =   0;
            if ( !int.TryParse(nd.Value, out tabID))
                return;
            // copy page
            int newTabID                        =   -1;
            string newName                      =   string.Format("Copy of '{0}'",nd.Text);
            string pageImage                    =   string.Empty;
            ModulesDB mDB                       =   new ModulesDB();
			// Finally use GetPageModules to access each Page and its modules in the Template Portal
			// and create them in the new Portal
			SqlDataReader dr	                =	null;
			SqlDataReader result	            =	null;
			try
			{
                try
				{
                    dr                          =   pagesDB.GetPortalPage(tabID);
                    dr.Read();
                    pageImage                   =   dr[StStr.DBPageSkin].ToString().Trim();
                    int parentTabId             =   Convert.IsDBNull(dr[StStr.DBParentPageID]) ? 0 : (int)dr[StStr.DBParentPageID];
                    int order                   =   (int)dr[StStr.DBPageOrder];
                    string str                  =   dr[StStr.DBAuthRoles].ToString();
                    newTabID	                =   pagesDB.AddPage(PortalID,parentTabId,newName,pageImage,order+1,3,0,0,0,0,0,str);
                }
                catch(Exception ex)
		        {
			        if (PagesManagerTrace.Sw.TraceError)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager CopyPage AddPage ex: {0}",ex),PagesManagerTrace.Sw.Info);
			        throw;
		        }
		        finally
		        {
			        if ( dr != null )
				        dr.Close(); 
                    dr      =   null;
			    }
				try
				{
                    dr						    =   pagesDB.GetPageCustomSettings(tabID);

					while (dr.Read()) 
					{
                        string DBSettingName    =   (string)dr[StStr.DBSettingName];
                        string DBSettingValue   =   (string)dr[StStr.DBSettingValue];
                        pagesDB.UpdatePageSettings(newTabID, DBSettingName,DBSettingValue);
                        if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager CopyPage update settings for newTabID: {0}, DBSettingName: {1}, DBSettingValue: {2}",
                                    newTabID,DBSettingName,DBSettingValue), PagesManagerTrace.Sw.Info);
					}
				}
		        catch(Exception ex)
		        {
			        if (PagesManagerTrace.Sw.TraceError)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager CopyPage GetPageSettings ex : {0}",ex),PagesManagerTrace.Sw.Info);
			        throw;
		        }
		        finally
		        {
			        if ( dr != null )
				        dr.Close(); 
                    dr      =   null;
		        }
                
                // now copy modules
                result					        =   mDB.GetPageModules(tabID);
				while(result.Read()) 
				{
					ModuleConfiguration m		=   new ModuleConfiguration(result,false);
					m.PageID					=   newTabID;
					// add the module to the new tab
					int newModuleID				=   mDB.AddModule(newTabID, m.ModuleOrder,m.ModuleSettingsID,
                                                            m.PaneName, m.ModuleTitle, 
						                                    m.ModuleDefID,	m.CacheTime, m.AuthorizedEditRoles, m.AuthorizedViewRoles,
						                                    m.AuthorizedAddRoles, m.AuthorizedDeleteRoles, m.AuthorizedPropertiesRoles,
						                                    m.AuthorizedMoveModuleRoles, m.AuthorizedDeleteModuleRoles,
						                                    m.ShowEveryWhere, m.SupportCollapsable);
                    if (PagesManagerTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager CopyPage newModuleID: {0}",newModuleID), PagesManagerTrace.Sw.Info);
					// At the end, get all ModuleConfiguration and save them in the new module
					try
					{
                        dr						=   mDB.GetModuleSettings(m.ModuleID);

						while (dr.Read()) 
						{
                            string DBSettingName    =   (string)dr[StStr.DBSettingName];
                            string DBSettingValue   =   (string)dr[StStr.DBSettingValue];
                            mDB.UpdateModuleSetting(newModuleID, DBSettingName,DBSettingValue ,(int)dr[StStr.DBSettingGroup]);
                            if (PagesManagerTrace.Sw.TraceVerbose)
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager CopyPage update settings for newModuleID: {0}, DBSettingName: {1}, DBSettingValue: {2}",
                                        newModuleID,DBSettingName,DBSettingValue), PagesManagerTrace.Sw.Info);
						}
					}
					catch(Exception ex)
					{
						if (PagesManagerTrace.Sw.TraceError)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager CopyPage GetModuleSettings ex : {0}",ex),PagesManagerTrace.Sw.Info);
						throw;
					}
					finally
					{
						if ( dr != null )
							dr.Close(); 
                        dr      =   null;
					}
						
				}
			}
			catch(Exception ex)
			{
				if (PagesManagerTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager CopyPage GetPagesModules ex: {0}.",ex),PagesManagerTrace.Sw.Info);
				throw;
			}
			finally
			{
				if ( dr != null )
					dr.Close(); 
				if ( result != null )
					result.Close(); 
			}
            // Add new node and refresh menus
            RadTreeNode nnd          =   new RadTreeNode(newName, newTabID.ToString());
            nnd.ContextMenuID        =   strPageMenu;
            nd.ParentNode.Nodes.Add(nnd);
            string wSkinID          =   pageImage.ToLower(CultureInfo.InvariantCulture).Trim();
            Hashtable skTb          =   portalSettings.GetSkinImageMenu(true);
            bool okSkin             =   (skTb[wSkinID] != null);
            if (okSkin)
            {
                nnd.Attributes["Skin"]   =   (string)skTb[wSkinID];
            }
            else
            {
                nnd.Attributes["Skin"]   =   (string)skTb["defaultskin"];
            }
            if (( nnd.ParentNode != null ) && (nnd.ParentNode.ParentNode == null ) )
                    nnd.ImageUrl     =   nnd.Attributes["Skin"];
            else    nnd.ImageUrl     =   string.Empty;
            SelectNode(nnd);
			// Invalidate cache
            ReloadPortal();
		}



		void RadTree1_NodeClick(object o, RadTreeNodeEventArgs e)
		{
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeClick Text:{0}, Selected: {1}", e.Node.Text,e.Node.Selected),PagesManagerTrace.Sw.Info);
	        SelectNode(e.Node);
        }

        /// <summary>
        /// Fills the RadGrid with information from selected node
        /// If no node, empties the grid
        /// </summary>
        protected void SelectNode(RadTreeNode selectedNode)
        {
            if ( selectedNode == null )
                return;
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager SelectNode BEG Text:{0}, Selected: {1}", selectedNode.Text,selectedNode.Selected),PagesManagerTrace.Sw.Info);
            RadGrid RadGrid2    =   (RadGrid)GridDock.ContentContainer.FindControl("RadGrid2");
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager SelectNode RadGrid2 null: {0}.", RadGrid2 == null ),PagesManagerTrace.Sw.Info);
            if ( RadGrid2 == null )
                return;
            selectedNode.Selected           =   true;
			DataTable InfoTb                =   new DataTable();
            const string colName            =   "Name";
            const string colParameter       =   "Parameter";

			InfoTb.Columns.Add(colName, typeof(string));
			InfoTb.Columns.Add(colParameter, typeof(string));
            try
            {

                DataRow rw                  =   InfoTb.NewRow();
                rw[colName]                 =   LocalizeHelper.Localize("AM_NAME", "Name");
                // suppress the Id before '-'
                string ntext                =   selectedNode.Text;
                int idx                     =   ntext.IndexOf('-');
                if ( idx != -1 )
                    ntext                   =   ntext.Substring(idx+1);
                rw[colParameter]            =   ntext;
                InfoTb.Rows.Add(rw);

                rw                          =   InfoTb.NewRow();
                rw[colName]                 =   "ID";
                rw[colParameter]            =   selectedNode.Value;
                InfoTb.Rows.Add(rw);
                // Root we must exist
                if (int.Parse("0"+selectedNode.Value) != 0)
                {
                    SqlDataReader dr            =   null;
                    try
                    {
                        int tabId               =   int.Parse(selectedNode.Value);
                        dr                      =   pagesDB.GetPortalPage(tabId);
                        while (dr.Read())
                        {
                            string pageImage    =   dr[StStr.DBPageSkin].ToString().Trim();
                            int parentTabId     =   Convert.IsDBNull(dr[StStr.DBParentPageID]) ? 0 : (int)dr[StStr.DBParentPageID];
                            bool hasModules     =   ((int)dr[StStr.DBPageNbModules]) != 0;

                            rw                  =   InfoTb.NewRow();
                            rw[colName]         =   LocalizeHelper.Localize("AM_TABIMAGE", "Image");
                            rw[colParameter]    =   pageImage;
                            InfoTb.Rows.Add(rw);

                            rw                  =   InfoTb.NewRow();
                            rw[colName]         =   "Parent";
                            RadTreeNode nd1 = RadTree1.FindNodeByValue(parentTabId.ToString());
                            if ( nd1 != null )
                            {
                                rw[colParameter] = nd1.Text;
                            }
                            else rw[colParameter] = parentTabId.ToString();
                            InfoTb.Rows.Add(rw);

                            rw                  =   InfoTb.NewRow();
                            rw[colName]         =   LocalizeHelper.Localize("AM_ORDER", "Order");
                            rw[colParameter]    =   dr[StStr.DBPageOrder];
                            InfoTb.Rows.Add(rw);

                            rw                  =   InfoTb.NewRow();
                            rw[colName]         =   LocalizeHelper.Localize("AM_HASMODULES", "Has Modules");
                            rw[colParameter]    =   hasModules.ToString();
                            InfoTb.Rows.Add(rw);

                            string str          =   dr[StStr.DBAuthRoles].ToString();
                            string[] aut        =   str.Split(new char[] { ';' },StringSplitOptions.RemoveEmptyEntries);
                            foreach (string st in aut)
                            {
                                if (st.Trim() == string.Empty)
                                    continue;
                                string t        =   st;
                                if (st == DBAdmin)
                                    t           =   CRMAdmin;
                                else if (st == DBAllUser)
                                    t           =   CRMAllUsers;
                                rw              =   InfoTb.NewRow();
                                rw[colName]     =   LocalizeHelper.Localize("AM_AUTHORIZE", "Authorized");
                                rw[colParameter]=   t;
                                InfoTb.Rows.Add(rw);
                            }
                            ADNPageFlags Flags  =   ADNPageFlags.Normal;
                            if ( dr[StStr.DBPageLayout] != DBNull.Value )
                                Flags           =  (ADNPageFlags)dr[StStr.DBPageLayout];
                            if ( Flags != ADNPageFlags.Normal )
                                for (int i=1 ; i <= (int)ADNPageFlags.OnlyAuthenticated; i <<= 1 )
                                {
                                    ADNPageFlags f                  =   (ADNPageFlags)i;
                                    if ( ( Flags & f ) == f )
                                    {
                                        rw                  =   InfoTb.NewRow();
                                        rw[colName]         =   LocalizeHelper.Localize("AM_SYSTEMFLAG", "System Flags");
                                        rw[colParameter]    =   f.ToString();
                                        InfoTb.Rows.Add(rw);
                                    }
                                }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ModuleTraceSwitch.Sw.TraceError)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager Select ex:{0}", ex),ModuleTraceSwitch.Sw.Info);
                    }
                    finally
                    {
                        if (dr != null)
                            dr.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager SelectNode Building ex:{0}", ex),ModuleTraceSwitch.Sw.Info);
            }
            try
            {
                RadGrid2.DataSource = InfoTb;
                RadGrid2.DataBind();
            }
            catch (Exception ex)
            {
                if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager SelectNode Binding ex:{0}", ex),ModuleTraceSwitch.Sw.Info);
            }
        }

		/// <summary>
		/// User has edited a page name, we change it
		/// </summary>
        void RadTree1_NodeEdit(object o, RadTreeNodeEditEventArgs e)
        {
			RadTreeNode sourceNode  =   e.Node;
			string ntext            =   e.Text;
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeEdit BEG Node.Text:{0}, newtext: {1}", sourceNode.Text,ntext),PagesManagerTrace.Sw.Info);
            string searchText       =   string.Format("{0}-",sourceNode.Value);
            int idx                 =   ntext.IndexOf(searchText);
            if (idx != -1)
            {
                ntext               =   ntext.Substring(idx + searchText.Length);
            }
            idx                     =   ntext.IndexOf('-');
            if (idx != -1)
            {
                ntext               =   ntext.Substring(idx + 1);
            }
            string txt              =   string.Format("{0}-{1}",sourceNode.Value,ntext);
            if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeEdit  {0}-{1} changed to {2}", sourceNode.Text, sourceNode.Value, ntext),PagesManagerTrace.Sw.Info);
			try
			{
				pagesDB.UpdatePageName(int.Parse(sourceNode.Value), ntext);
				sourceNode.Text         = txt;
                // refresh the radgrid
                SelectNode(sourceNode);
			}
			catch (Exception ex)
			{
				if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager RadTree1_NodeEdit ex:{0}", ex),ModuleTraceSwitch.Sw.Info);
                throw;
			}
		}

		/// <summary>
		/// User has moved a node
		/// </summary>
        void RadTree1_NodeDrop(object o, RadTreeNodeDragDropEventArgs e)
        {
            // Fetch event data 
            RadTreeNode sourceNode		= e.SourceDragNode;
            RadTreeNode destNode		= e.DestDragNode;
			if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeDrop BEG sourceNode.Text: {0}.",sourceNode.Text),PagesManagerTrace.Sw.Info);
    
            // node may have been dropped outside treeviews, or on itself
			// we can't move to root (destNode.Parent == null)
			// We don't accept inversing hierarchy
			if (destNode == null || sourceNode.Equals(destNode) || destNode.Parent == null || sourceNode.IsAncestorOf(destNode) )
				return;
			// We don't move first level nodes
            //if ( sourceNode.Parent.Equals(RadTree1.Nodes[0]) )
			//	return;
            RadTreeNode AdminNode   =   RadTree1.FindNodeByValue(StStr.strPageAdminID);
            if ( AdminNode != null &&
                !Settings[AStr.moveAdmin].ToBool() && 
                sourceNode.IsDescendantOf(AdminNode) )
                return;
			RadTreeViewDropPosition d	=	e.DropPosition;

			if (PagesManagerTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeDrop  {0} -{1}- {2}",sourceNode.Text,d,destNode.Text),PagesManagerTrace.Sw.Info);
			try
			{
				bool changeParent       =   (destNode.ParentNode != sourceNode.ParentNode );
				switch (d)
				{
					case RadTreeViewDropPosition.Above:
						sourceNode.Owner.Nodes.Remove(sourceNode);
						destNode.InsertBefore(sourceNode);
						if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeDrop: {0} changeParent: {1}", sourceNode.Text, changeParent),PagesManagerTrace.Sw.Info);
						if (changeParent)
							ChangeParentPage(sourceNode, destNode.ParentNode);
						OrderPages(destNode.ParentNode);
						break;
					case RadTreeViewDropPosition.Below:
						sourceNode.Owner.Nodes.Remove(sourceNode);
						destNode.InsertAfter(sourceNode);
						if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeDrop: {0} changeParent: {1}", sourceNode.Text, changeParent),PagesManagerTrace.Sw.Info);
						if (changeParent)
							ChangeParentPage(sourceNode, destNode.ParentNode);
						OrderPages(destNode.ParentNode);
						break;
					case RadTreeViewDropPosition.Over:
						// we don't accept putting pages on pages containing modules
						if (destNode.Category == "Page")
						{
							if (PagesManagerTrace.Sw.TraceVerbose)
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeDrop: {0} destNode.Category: {1}", sourceNode.Text, destNode.Category),PagesManagerTrace.Sw.Info);
							return;
						}
                        // different rules here
				        if (destNode.ParentNode == sourceNode.ParentNode )
                            changeParent       =   true;
				        else if (destNode == sourceNode.ParentNode )
                            changeParent       =   false;
						if (PagesManagerTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager RadTree1_NodeDrop: {0} changeParent: {1}", sourceNode.Text, changeParent),PagesManagerTrace.Sw.Info);
						sourceNode.Owner.Nodes.Remove(sourceNode);
						destNode.Nodes.Add(sourceNode);
						if (changeParent)
							ChangeParentPage(sourceNode, destNode);
						OrderPages(destNode);
						break;
					default:
						return;
				}
                // Display or not the associated icon
                if (( sourceNode.ParentNode != null ) && (sourceNode.ParentNode.ParentNode == null ) )
                        sourceNode.ImageUrl   =   sourceNode.Attributes["Skin"];
                else    sourceNode.ImageUrl   =   string.Empty;
				// Expand destination node to see result of swap immediately.
                if ( sourceNode.ParentNode != null )
				    sourceNode.ParentNode.ExpandChildNodes();
			}
			catch (Exception ex)
			{
				if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager RadTree1_NodeDrop ex:{0}", ex),ModuleTraceSwitch.Sw.Info);
			}
        }

        /// <summary>
		/// Given the tabID of a tab, this function selects the right tab in the provided treeview
		/// </summary>
		/// <param name="tabID">tabID of the tab that needs to be selected</param>
		private bool SelectPage (string strID, RadTreeNodeCollection Nodes)
		{
			foreach (RadTreeNode nd in Nodes)
			{
				if(nd.Value == strID)
				{
                    nd.Selected     =   true;
					SelectNode(nd);
					return true;
				}
                // found in this path, expand all until top
                if ( nd.Nodes.Count > 0 && SelectPage(strID,nd.Nodes) )
                {
                    nd.Expanded     =   true;
                    return true;
                }
			}
			return false;
		}

		/// <summary>
		/// Change the parent Page for a Page
		/// </summary>
		/// <param name="sourceNode">treenode for the page to change</param>
		/// <param name="destNode">treenode for new parent</param>
		void ChangeParentPage(RadTreeNode sourceNode, RadTreeNode destNode)
		{
			try
			{
				if (PagesManagerTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager ChangeParentPage  {0} to {1}",sourceNode.Text,destNode.Text),PagesManagerTrace.Sw.Info);
				int tabId		= int.Parse(sourceNode.Value);
				int parentId	= int.Parse(destNode.Value);
				// write to database
				pagesDB.UpdatePageParent(tabId, parentId, PortalID);
				// Invalidate cache
                ReloadPortal();
			}
			catch (Exception ex)
			{
				if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager ChangeParentPage  ex: {0}",ex),ModuleTraceSwitch.Sw.Info);
				throw;
			}
		}

		/// <summary>
        /// The OrderPages helper method is used to reset 
        /// the display order for page within the portal
        /// </summary>
        private void OrderPages (RadTreeNode Owner) 
        {
			try
			{
				if (PagesManagerTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager OrderPages: {0}-{1}",Owner.Text,Owner.Value),PagesManagerTrace.Sw.Info);
				int i				= 1;
				foreach (RadTreeNode n in Owner.Nodes)
				{
					// number the items 1, 3, 5, etc. to provide an empty order
					// number when moving items up and down in the list.
					int newOrder	= i;
					int tabId		= int.Parse(n.Value);
					i				+= 2;
				    if (PagesManagerTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]PortalPagesManager OrderPages i: {0}, Text: {1}, Value: {2}",i,n.Text,n.Value),PagesManagerTrace.Sw.Info);
					// rewrite page order to database
					pagesDB.UpdatePageOrder(tabId, newOrder);
				}
                ReloadPortal();
			}
			catch (Exception ex)
			{
				if (ModuleTraceSwitch.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]PortalPagesManager OrderPages  ex: {0}", ex),ModuleTraceSwitch.Sw.Info);
				throw;
			}
		}
    
        #region Dock management

        const string pgCookieName   =   "AddonNice_PageManager";
        
        protected override string DockWindowCookieName
        {
            get
            {
                return pgCookieName;
            }
        }

        protected override RadDockLayout DockWindowLayout
        {
            get
            {
                return RadDockLayout1;
            }
        }
        #endregion Dock management

        #region Std Overrides

        override protected void OnInit(EventArgs e)
		{
			if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PortalPagesManager OnInit BEG.",ModuleTraceSwitch.Sw.Info);
			InitializeComponent();
			base.OnInit(e);
			if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]PortalPagesManager OnInit END.",ModuleTraceSwitch.Sw.Info);
		}

        private void InitializeComponent() 
        {
			Load					        +=  new EventHandler(Page_Load);
            RadTree1.NodeDrop               +=  new RadTreeViewDragDropEventHandler(RadTree1_NodeDrop);
            RadTree1.NodeEdit               +=  new RadTreeViewEditEventHandler(RadTree1_NodeEdit);
			RadTree1.NodeClick		        +=  new RadTreeViewEventHandler(RadTree1_NodeClick);
            RadTree1.ContextMenuItemClick   +=  new RadTreeViewContextMenuEventHandler(RadTree1_ContextMenuItemClick);
            GridDock.Command                +=  new DockCommandEventHandler(GridDock_Command);
            RadDockLayout1.LoadDockLayout   +=  new DockLayoutEventHandler(DockWindowLayout_LoadDockLayout);
            RadDockLayout1.SaveDockLayout   +=  new DockLayoutEventHandler(DockWindowLayout_SaveDockLayout);
		}

		#endregion

    }
}


